/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpb.projetoesa.dados;

import br.ufpb.projetoesa.exceptions.ArquivoBinInexistenteException;
import br.ufpb.projetoesa.exceptions.ProjetoInexistenteException;
import br.ufpb.projetoesa.exceptions.ProjetoInvalidoException;
import br.ufpb.projetoesa.exceptions.ProjetoVazioException;
import br.ufpb.projetoesa.negocio.Projeto;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author kawe
 */
public class ProjetoDAOBin implements ProjetoDAO{

    private ObjectInputStream input;
    private ObjectOutputStream output;
    private File arquivo;
    Map<String, Projeto> mapProjeto;
    private static ProjetoDAOBin daoProjetoBin;
    
    
    //Singleton
    public static ProjetoDAOBin getInstance(){
        if(daoProjetoBin == null){
            return new ProjetoDAOBin();
        }else{
            return daoProjetoBin;
        }
        
    }
    
    public ProjetoDAOBin(){
        this.arquivo = new File("projetos.bin");
        this.mapProjeto = new HashMap<String, Projeto>();
    }
    
    public void salvarProjetosBin(){
        try {
            output = new ObjectOutputStream(new FileOutputStream(arquivo));
            output.writeObject(mapProjeto);
            output.flush();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        
    }
    
    public void recuperaProjetosBin(){
        
        try {
            input = new ObjectInputStream(new FileInputStream(arquivo));
            this.mapProjeto = (HashMap<String, Projeto>) input.readObject();
            input.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    
    public void criarArquivoBinProjeto() throws ArquivoBinInexistenteException{
        try {
            
            File fileProjeto = new File("projetos.bin");
            if(!fileProjeto.exists()){
                fileProjeto.createNewFile();
            }
            
            
        } catch (IOException e) {
            throw new ArquivoBinInexistenteException("Erro ao tentar criar o arquivo binário do projeto\n");
        }
        
    }
    
    
    
    public void inserir(Projeto projeto) throws ProjetoInvalidoException, ProjetoInexistenteException{
        if(projeto != null){
            if(!mapProjeto.containsValue(projeto)){
                mapProjeto.put(projeto.getId(), projeto);
            }else{
                throw new ProjetoInvalidoException("Erro ao tentar inserir, já existe esse projeto");
            }
            
        }else{
            throw new ProjetoInexistenteException("Erro ao tentar inserir o projeto, tente novamente");
        }
       
        
        
    }

    @Override
    public void remover(Projeto projeto) throws ProjetoInexistenteException, ProjetoInvalidoException {
        
        
        if(projeto != null){
            if(!mapProjeto.isEmpty()){
                if(mapProjeto.containsValue(projeto)){
                    mapProjeto.remove(projeto);
                }else{
                    throw new ProjetoInexistenteException("Projeto não está cadastrado");
                }
            }else{
                throw new ProjetoVazioException("Não existe projetos cadastrados no momento");
            }
        } else{
            throw new ProjetoInvalidoException("Ocorreu um erro na remoção do projeto");
        }
        
        
    }

    @Override
    public Projeto pesquisarID(String id) throws ProjetoInexistenteException,ProjetoVazioException {
        if(id != null ){
            if(!mapProjeto.isEmpty() ){
                if(mapProjeto.containsKey(id)){
                    return mapProjeto.get(id);
                }else{
                    throw new ProjetoInexistenteException("Projeto não está cadastrado");
                }
                
            }else{
                throw new ProjetoVazioException("Não existe projeto cadastrados");
            }
            
        }else{
            throw new ProjetoInexistenteException("Erro ao tentar pesquisar o projeto");
        }
        
    }

    @Override
    public Projeto pesquisar(String nome) throws ProjetoInexistenteException, ProjetoInvalidoException{
        if(nome != null){
            Iterator<Projeto> iterator = this.mapProjeto.values().iterator();
            while(iterator.hasNext()){
                Projeto temp = (Projeto) iterator.next();
                if(nome.toLowerCase().startsWith(temp.getNome().toLowerCase())){
                    return temp;
                }
            }
            throw new ProjetoInexistenteException("Não existe projeto com o nome " + nome + " cadastrado");
            
        } else{
            throw new ProjetoInvalidoException("Projeto" + nome + " não existe");
        }
    }

    @Override
    public void atualizar(Projeto projeto) throws ProjetoInexistenteException {
        if(projeto != null){
            if(!mapProjeto.isEmpty()){
                if(mapProjeto.containsValue(projeto)){
                    mapProjeto.remove(projeto.getId());
                    mapProjeto.put(projeto.getId(), projeto);
                } else{
                    throw new ProjetoInexistenteException("Projeto " + projeto.getNome() + " não existe");
                }
                
            }else{
                throw new ProjetoVazioException("Não existe projetos cadastrados");
            }
        }else{
            throw new ProjetoInvalidoException("Erro ao alterar");
        }
            
            
    }
    
}
